﻿/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.fixed.cellMerge.js
* 开发 落阳
* 最近更新：2017-11-22
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2017 Lixilin personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");

    $.extend($.fn.datagrid.extensions, {

        mergeRecordsPropertyName: "mergeRecords",

        mergeRangePositionsPropertyName: "mergePositions",

        mergeCells: $.fn.datagrid.methods.mergeCells,

        endEdit: $.fn.datagrid.methods.endEdit
    });

    var mergeCells = function (target, mergeInfo) {
        var t = $(target),
            opts = $.data(target, "datagrid").options;

        if (mergeInfo.rowspan == 1 && mergeInfo.colspan == 1) {
            return;
        }
        mergeInfo.type = mergeInfo.type || "body";
        var tr = opts.finder.getTr(target, (mergeInfo.index != undefined ? mergeInfo.index : mergeInfo.id), mergeInfo.type);
        if (!tr.length) {
            return;
        }
        //如果合并的行是横跨冻结列和常规列，则认为合并行为无效
        var frozenFields = t.datagrid("getColumnFields", true);
        var normalFields = t.datagrid("getColumnFields", false);
        var fieldIndex = getFieldIndex(frozenFields, normalFields, mergeInfo.field);
        if (fieldIndex.fieldIndexInFrozen != -1 && (fieldIndex.fieldIndexInFrozen + (mergeInfo.colspan || 1) - 1) > frozenFields.length - 1) {
            console.log("合并的行横跨冻结列和常规列，合并行为无效");
            return;
        }
        var ret = $.fn.datagrid.extensions.mergeCells.call(target, t, mergeInfo);

        if (!opts[$.fn.datagrid.extensions.mergeRecordsPropertyName]) { opts[$.fn.datagrid.extensions.mergeRecordsPropertyName] = []; }
        var theMergeInfo = {
            type: mergeInfo.type,
            rowspan: mergeInfo.rowspan || 1,
            colspan: mergeInfo.colspan || 1,
            field: mergeInfo.field,
            index: mergeInfo.index,
            id: mergeInfo.id
        };
        opts[$.fn.datagrid.extensions.mergeRecordsPropertyName].push(theMergeInfo);

        if (!opts[$.fn.datagrid.extensions.mergeRangePositionsPropertyName]) { opts[$.fn.datagrid.extensions.mergeRangePositionsPropertyName] = []; }

        opts[$.fn.datagrid.extensions.mergeRangePositionsPropertyName].push(getMergeRangePosition(target, opts, frozenFields, normalFields, theMergeInfo));

        return ret;
    };

    var getMergeRecords = function (target) {
        return $.data(target, "datagrid").options[$.fn.datagrid.extensions.mergeRecordsPropertyName] || [];
    };

    var getMergePositions = function (target) {
        return $.data(target, "datagrid").options[$.fn.datagrid.extensions.mergeRangePositionsPropertyName] || [];
    };

    var getMergeRangePosition = function (target, opts, frozenFields, normalFields, mergeInfo) {
        if (mergeInfo.type != "body") { return null; }

        var indexs = getFieldIndex(frozenFields, normalFields, mergeInfo.field);
        var fieldIndexInFrozen = indexs.fieldIndexInFrozen,
            fieldIndexInNormal = indexs.fieldIndexInNormal,
            fieldIndex = indexs.fieldIndex;

        var ranges = [];
        var beginRowIndex = mergeInfo.index, endRowIndex = beginRowIndex + mergeInfo.rowspan - 1;
        var beginFieldIndex = fieldIndex, endFieldIndex = beginFieldIndex + mergeInfo.colspan - 1;

        var crossFields = [];
        if (fieldIndexInFrozen != -1) {
            for (var i = fieldIndexInFrozen; i < frozenFields.length && i <= endFieldIndex; i++) {
                crossFields.push(frozenFields[i]);
            }
        } else {
            for (var i = fieldIndexInNormal; i < normalFields.length && i <= endFieldIndex; i++) {
                crossFields.push(normalFields[i]);
            }
        }

        return {
            beginRowIndex: beginRowIndex,
            endRowIndex: endRowIndex,
            beginFieldIndex: beginFieldIndex,
            endFieldIndex: endFieldIndex,
            beginField: mergeInfo.field,
            endField: crossFields[crossFields.length - 1],
            crossFields: crossFields
        };
    };

    var endEdit = function (target, index) {
        var t = $(target), opts = $.data(target, "datagrid").options,
            ret = $.fn.datagrid.extensions.endEdit.call(target, t, index);
        mergePositions = getMergePositions(target);

        if (!mergePositions.length) { return ret; }

        var frozenFields = t.datagrid("getColumnFields", true),
            normalFields = t.datagrid("getColumnFields", false);
        var rows = t.datagrid("getRows");

        $.array.forEach([frozenFields, normalFields], function (theFields) {
            $.array.forEach(theFields, function (field) {
                var column = t.datagrid('getColumnOption', field);
                if (!hasEditor(column, field)) { return; }
                console.log("列[" + field + "]存在编辑器");
                var rowIndex = index;
                var fieldIndex = getFieldIndex(frozenFields, normalFields, field).fieldIndex;
                for (var i = 0; i < mergePositions.length; i++) {
                    console.log("循环合并的单元格范围[" + i + "]");
                    var position = mergePositions[i];
                    if (position.beginRowIndex == rowIndex && position.beginFieldIndex == fieldIndex) {
                        console.log("当前数据行[" + rowIndex + "]当前数据列[" + field + "](" + fieldIndex + ")是循环范围对象[" + position.beginRowIndex + "," + position.beginFieldIndex + "]的开始坐标");
                        var value = (column.formatter && $.isFunction(column.formatter)) ? column.formatter.call(target, rows[rowIndex][field], rows[rowIndex], rowIndex) : rows[rowIndex][field];
                        console.log("当前单元格值：" + value);
                        console.log("开始设置循环范围内其他位置的单元格");
                        for (var tempRowIndex = position.beginRowIndex; tempRowIndex <= position.endRowIndex; tempRowIndex++) {
                            var tempRow = rows[tempRowIndex];
                            console.log("数据行[" + tempRowIndex + "]");
                            var needUpdate = false;
                            var needUpdateFields = [];
                            for (var tempFieldIndex = position.beginFieldIndex; tempFieldIndex <= position.endFieldIndex; tempFieldIndex++) {
                                if (tempRowIndex == rowIndex && tempFieldIndex == fieldIndex) { console.log("自己单元格，略过"); continue; }
                                needUpdate = true;
                                var tempField = position.crossFields[tempFieldIndex - position.beginFieldIndex];
                                console.log("数据列[" + tempField + "(" + tempFieldIndex + ")]");
                                needUpdateFields.push(tempField);
                                //3 4 5 6 7
                                //A B C D E
                                //3=>0
                                //4=>1
                                //5=>2
                                tempRow[tempField] = value;
                                var rowDom = getRowDom(target, tempRowIndex);
                                if (rowDom.hasClass("datagrid-row-editing")) {
                                    var editor = t.datagrid("getEditor", { index: tempRowIndex, field: tempField });
                                    if (editor) {
                                        editor.actions && editor.actions.setValue(editor.target[0], value);
                                    } else {
                                        var cellDom = getCellDom(target, { index: tempRowIndex, field: tempField });
                                        cellDom.html(value);
                                    }
                                } else {
                                    var cellDom = getCellDom(target, { index: tempRowIndex, field: tempField });
                                    cellDom.html(value);
                                }
                                console.log("预计设置：数据行[" + tempRowIndex + "]数据列[" + tempField + "(" + tempFieldIndex + ")]的value为[" + value + "]");
                            }
                            if (needUpdate) {
                                console.log("完成数据行更新：数据行[" + tempRowIndex + "]，数据列[" + needUpdateFields.join(",") + "]");
                            }
                        }
                    }
                }
            });
        });

        return ret;
    };

    var getFieldIndex = function (frozenFields, normalFields, field) {
        var fieldIndex = -1, fieldIndexInFrozen = -1, fieldIndexInNormal = -1;
        for (var i = 0; i < frozenFields.length; i++) {
            if (frozenFields[i] == field) { fieldIndexInFrozen = i; break; }
        }
        for (var i = 0; (fieldIndexInFrozen == -1 && i < normalFields.length) ; i++) {
            if (normalFields[i] == field) { fieldIndexInNormal = i; break; }
        }
        fieldIndex = fieldIndexInFrozen != -1 ? fieldIndexInFrozen : (frozenFields.length + fieldIndexInNormal);

        return {
            fieldIndexInFrozen: fieldIndexInFrozen,
            fieldIndexInNormal: fieldIndexInNormal,
            fieldIndex: fieldIndex
        };
    };

    var hasEditor = function (column, field) {
        if (!column.editor) { return false; }

        var flag = typeof (column.editor) == "string", editorType = flag ? column.editor : column.editor.type, editorAction = $.fn.datagrid.defaults.editors[editorType];
        if (!editorAction) { editorType = undefined; }
        if (!editorType) { return false; }

        return true;
    };

    var getRowDom = function (target, index) {
        if (!$.isNumeric(index) || index < 0) { return $(); }
        var t = $(target), panel = t.datagrid("getPanel");
        return panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row[datagrid-row-index=" + index + "]");
    };

    var getColumnDom = function (target, param) {
        if ($.string.isNullOrEmpty(param)) { return $(); }
        var t = $(target), panel = t.datagrid("getPanel"),
            isObject = !$.string.isString(param),
            field = isObject ? param.field : param,
            header = isObject ? param.header : false,
            dom = panel.find("div.datagrid-view tr.datagrid-row td[field=" + field + "]");
        if (header) { dom = dom.add(panel.find("div.datagrid-view tr.datagrid-header-row td[field=" + field + "]")); }
        return dom;
    };

    var getCellDom = function (target, pos) {
        if (!pos || !pos.field || !$.isNumeric(pos.index) || pos.index < 0) { return $(); }
        var tr = getColumnDom(target, pos.index);
        return tr.find("td[field=" + pos.field + "] .datagrid-cell");
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  重写 easyui-datagrid 的原生方法 mergeCells ，以支持“合并单元格情况下的编辑操作同时生效到被合并的单元格”的扩展；
        mergeCells: function (jq, fields) { return jq.each(function () { mergeCells(this, fields); }); },

        //  重写 easyui-datagrid 的原生方法 endEdit ，以支持“合并单元格情况下的编辑操作同时生效到被合并的单元格”的扩展；
        endEdit: function (jq, index) { return jq.each(function () { endEdit(this, index); }); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中进行过合并单元格操作的记录数据所构成的一个数组；
        //  返回值：返回一个数组，数组中每一个元素都是合并单元格操作的参数对象，如果从未进行过合并单元格操作，则返回1个空数组
        getMergeRecords: function (jq) { return getMergeRecords(jq[0]); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中进行过合并单元格操作的单元格范围坐标所构成的一个数组；
        //  返回值：返回一个数组，数组中每一个元素都是合并单元格操作所影响的单元格范围坐标对象，如果从未进行过合并单元格操作，则返回1个空数组
        getMergePositions: function (jq) { return getMergePositions(jq[0]); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);